package com.freesky.common.jackson;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.freesky.common.annotation.Desensitized;
import com.freesky.common.utils.DesensitizedUtil;

import java.io.IOException;
import java.util.Objects;

/**
 * 脱敏JSON序列化工具
 */
public class DesensitizedJsonSerializer extends StdSerializer<String> implements ContextualSerializer {

    private static final long serialVersionUID = 1L;

    private Desensitized.DesensitizedType type;

    public DesensitizedJsonSerializer() {
        super(String.class);
    }

    public DesensitizedJsonSerializer(Desensitized.DesensitizedType type) {
        super(String.class);
        this.type = type;
    }

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }

        String result = value;
        switch (type) {
            case PHONE:
                result = DesensitizedUtil.maskPhone(value);
                break;
            case USER_NAME:
                result = DesensitizedUtil.maskName(value);
                break;
            case EMAIL:
                result = DesensitizedUtil.maskEmail(value);
                break;
            case ID_CARD:
                result = DesensitizedUtil.maskIdCard(value);
                break;
            case BANK_CARD:
                result = DesensitizedUtil.maskBankCard(value);
                break;
            case ADDRESS:
                result = DesensitizedUtil.maskAddress(value);
                break;
            default:
                break;
        }
        gen.writeString(result);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        if (property == null) {
            return this;
        }
        Desensitized desensitized = property.getAnnotation(Desensitized.class);
        if (Objects.nonNull(desensitized) && String.class.isAssignableFrom(property.getType().getRawClass())) {
            return new DesensitizedJsonSerializer(desensitized.type());
        }
        return prov.findValueSerializer(property.getType(), property);
    }
} 